

interface DKeyValue {
    key: string | number;
    value: number;
}

export class CfgTable {

    private _name: string;
    private _data: any[];
    private _mk: string;
    private _indexDict: { [key: string]: any } = {};
    private _groupDict: { [key: string]: any } = {};

    public constructor(name: string) {
        this._name = name;
    }

    public get name() {
        return this._name;
    }

    public load(data: any[], mk: string) {
        this._data = data;
        this._mk = mk;
        this.makeIndex(this._mk);
    }

    public makeIndex(key: string) {
        let indexObj = {};
        this._indexDict[key] = indexObj;
        for (let item of this._data) {
            indexObj[item[key]] = item;
        }
    }

    public getItem(id: any) {
        return this.getItemByKey(this._mk, id);
    }

    public getItemByKey(key: string, id: any) {
        return this._indexDict[key][id];
    }

    public makeGroup(gkey: string) {
        let groupObj = {};
        this._groupDict[gkey] = groupObj;
        for (let item of this._data) {
            let gkv = item[gkey];
            if (!groupObj[gkv]) {
                groupObj[gkv] = [];
            }
            groupObj[gkv].push(item);
        }
    }

    public getItemsByGroup(gkey: string, gkv: string | number): any[] {
        return this._groupDict[gkey][gkv];
    }

    public find(condList: DKeyValue[]) {
        let result = [];
        for (let item of this._data) {
            let isMatch = true;
            for (let cond of condList) {
                if (item[cond.key] != cond.value) {
                    isMatch = false;
                    break;
                }
            }
            if (isMatch) {
                result.push(item);
            }
        }
        return result;
    }

    public findOne(condList: DKeyValue[]) {
        for (let item of this._data) {
            let isMatch = true;
            for (let cond of condList) {
                if (item[cond.key] != cond.value) {
                    isMatch = false;
                    break;
                }
            }
            if (isMatch) {
                return item;
            }
        }
    }

    public get items() {
        return this._data;
    }

}

